package covertjava.protect;

import java.security.*;
import java.security.spec.*;
import java.io.*;
import java.text.*;
import covertjava.util.*;
import sun.misc.BASE64Decoder;
import java.util.Date;
import java.net.InetAddress;
import java.net.*;

/**
 * <p>Reads the license parameters and verifies their authenticity using the
 * license string. The license string is a digital signature that is verfied using
 * the public key of asymmetric algorithm</p>
 * <p>Copyright: Copyright (c) 2004 Sams Publishing</p>
 * @author Alex Kalinovsky
 * @version 1.0
 */
public class LicenseManager {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    String home = System.getProperty("home", "..");
    AppProperties licenseProps;
    private String host;
    private String ip;
    private Date expires;

    public static final String CHARSET = "UTF-16";

    public LicenseManager(String licenseFileName) throws Exception {
        this.licenseProps = new AppProperties(home + File.separator + licenseFileName);
        this.host = licenseProps.getProperty("host");
        this.ip = licenseProps.getProperty("ip");
        String expiresString = licenseProps.getProperty("expires");
        this.expires = this.dateFormat.parse(expiresString);      // Make sure the date format is valid

        System.out.println("License information read:");
        System.out.println("   host=" + host);
        System.out.println("   ip=" + ip);
        System.out.println("   expires=" + expires);
    }


    public boolean isLicenseExpired() {
        Date today = new Date();
        return today.after(this.expires);
    }

    public boolean isHostAllowed() {
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            if (localHost.getHostName().equals(this.host) ||
                localHost.getHostAddress().equals(this.ip))
                return true;
        }
        catch (UnknownHostException ex) {
        }
        return false;
    }


    protected String getLicenseString() throws Exception {
        return this.host + this.ip + this.expires;
    }

    public void verifySerialNumber(String keyFileName) throws Exception {
        String keyFilePath = this.home + File.separator + keyFileName;
        FileInputStream stream = new FileInputStream(keyFilePath);
        byte[] encodedPubKey = new byte[stream.available()];
        stream.read(encodedPubKey);
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encodedPubKey);
        KeyFactory keyFactory = KeyFactory.getInstance("DSA");
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);

        byte[] licenseData = getLicenseString().getBytes(CHARSET);
        String encodedSig = this.licenseProps.getProperty("serial");
        if (encodedSig == null || encodedSig.length() == 0)
            throw new InternalError("Serial number is missing");
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] serialSig = decoder.decodeBuffer(encodedSig);

        Signature signature = Signature.getInstance("SHA1withDSA");
        signature.initVerify(publicKey);
        signature.update(licenseData);
        if (signature.verify(serialSig) == false)
            throw new InternalError("Invalid serial number");
    }

}
